﻿using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;

namespace Jayden.Dll.Web.Styles
{
	public sealed class CssHelper
	{
		public static CssHelper Instance = new CssHelper();

		public const string MimeType = "text/css";
		public const string LinkRel = "stylesheet";

		public const string AllSelector = "*";
		public const string ClassSelector = ".";
		public const string IdSelector = "#";
		public const string InsideSelector = " ";
		public const string ChildrenSelector = ">";
		public const string ImmediatlyAfterSelector = "+";
		public const string ImmediatlyBeforeSelector = "~";

		public const string LinkSelector = ":link";
		public const string VisitedSelector = ":visited";
		public const string ActiveSelector = ":active";
		public const string HoverSelector = ":hover";
		public const string FocusSelector = ":focus";

		public const string FirstLetterSelector = ":first-letter";
		public const string FirstLineSelector = ":first-line";
		public const string FirstChildSelector = ":first-child";
		public const string FirstOfTypeSelector = ":first-of-type";
		public const string OnlyOfTypeSelector = ":only-of-type";
		public const string OnlyChildSelector = ":only-child";
		public const string NthSelector = ":nth-child";

		public const string InsertBeforeSelector = ":before";
		public const string InsertAfterSelector = ":after";
		public const string LangSelector = ":lang";

		private CssHelper() { }

		public static string ToCssColor(Color color)
		{
			string cssValue = ColorTranslator.ToHtml(color).ToLowerInvariant();
			if (cssValue.Length == 7 && cssValue[0] == '#' && cssValue[1] == cssValue[2] && cssValue[3] == cssValue[4] && cssValue[5] == cssValue[6])
				cssValue = "#" + cssValue[1] + cssValue[3] + cssValue[5];
			return cssValue;
		}
		public static Color FromCssColor(string cssColor)
		{
			if (cssColor.Length == 4 &&cssColor[0] == '#')
				cssColor = "#" + cssColor[1] + cssColor[1] + cssColor[2] + cssColor[2] + cssColor[3] + cssColor[3];
			return ColorTranslator.FromHtml(cssColor.Trim());
		}

		public static CssFile Load(string filename)
		{
			string text = File.ReadAllText(filename);
			return ParseCss(text);
		}

		public static string ClearComments(string css)
		{
			string start = "/*";
			string end = "*/";
			int next = 0;
			int index = css.IndexOf(start, next);
			while (index >= 0)
			{
				next = css.IndexOf(end, index + start.Length);
				if (next == -1)
					next = css.Length - end.Length;
				css = css.Remove(index, next - index + end.Length);
				next = index;
				index = css.IndexOf(start, next);
			}
			return css.Trim();
		}

		public static CssFile ParseCss(string css)
		{
			string patternComments = "\\/\\*.*\\*\\/";
			Regex regexComments = new Regex(patternComments, RegexOptions.Multiline);
			string noComments = regexComments.Replace(css, string.Empty);

			noComments = ClearComments(noComments);

			string patternElements = "[^{}]*{[^{}]*}";
			Regex regexElements = new Regex(patternElements, RegexOptions.Singleline);
			MatchCollection matches = regexElements.Matches(noComments);

			string partsSelector = "([^{}]*){([^{}]*)}";

			CssFile file = new CssFile();

			foreach (Match match in matches)
			{
				string cssElementStr = match.Value;
				Match parts = Regex.Match(cssElementStr, partsSelector, RegexOptions.Singleline);

				if (parts.Success && parts.Groups.Count == 3)
				{
					string[] selectors = parts.Groups[1].Value.Trim().Split(',');
					string[] properties = parts.Groups[2].Value.Trim().Split(';');

					CssElement element = new CssElement(selectors);
					foreach (string p in properties)
					{
						int index = p.IndexOf(':');
						if (index != -1)
						{
							string name = p.Substring(0, index).Trim();
							string value = p.Substring(index + 1).Trim();
							element.AddProperty(name, value);
						}
					}

					file.AddElement(element);
				}
			}

			return file;
		}

	}
}
